﻿using BGYXControlLibrary.Common;
using BGYXControlLibrary.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace BGYXControlLibrary
{
    public class BGYX_Button : Button
    {
        #region 按钮风格颜色定义

        private readonly Brush Secondary_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#80dededf"));
        private readonly Brush Secondary_BackgroundColor = Brushes.White;
        private readonly Color Secondary_PressColor = (Color)ColorConverter.ConvertFromString("#f5f5f5");
        private readonly Color Secondary_MouseOverColor = (Color)ColorConverter.ConvertFromString("#f9f9f9");

        private readonly Brush Primary_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#8075abef"));
        private readonly Brush Primary_BackgroundColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#5d9cec"));
        private readonly Color Primary_PressColor = (Color)ColorConverter.ConvertFromString("#2f80e7");
        private readonly Color Primary_MouseOverColor = (Color)ColorConverter.ConvertFromString("#3b87e8");

        private readonly Brush Success_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#8047cb67"));
        private readonly Brush Success_BackgroundColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#27c24c"));
        private readonly Color Success_PressColor = (Color)ColorConverter.ConvertFromString("#1e983b");
        private readonly Color Success_MouseOverColor = (Color)ColorConverter.ConvertFromString("#21a240");

        private readonly Brush Info_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#8044c2e9"));
        private readonly Brush Info_BackgroundColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#23b7e5"));
        private readonly Color Info_PressColor = (Color)ColorConverter.ConvertFromString("#1797be");
        private readonly Color Info_MouseOverColor = (Color)ColorConverter.ConvertFromString("#18a0ca");

        private readonly Brush Warning_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#80de802b"));
        private readonly Brush Warning_BackgroundColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#ff902b"));
        private readonly Color Warning_PressColor = (Color)ColorConverter.ConvertFromString("#f77600");
        private readonly Color Warning_MouseOverColor = (Color)ColorConverter.ConvertFromString("#ff7c05");

        private readonly Brush Danger_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#80f26a6a"));
        private readonly Brush Danger_BackgroundColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#f05050"));
        private readonly Color Danger_PressColor = (Color)ColorConverter.ConvertFromString("#ec2121");
        private readonly Color Danger_MouseOverColor = (Color)ColorConverter.ConvertFromString("#ed2d2d");

        private readonly Brush Inverse_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#80364047"));
        private readonly Brush Inverse_BackgroundColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#131e26"));
        private readonly Color Inverse_PressColor = (Color)ColorConverter.ConvertFromString("#020304");
        private readonly Color Inverse_MouseOverColor = (Color)ColorConverter.ConvertFromString("#060a0d");

        private Brush Green_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#8055c6aa"));
        private Brush Green_BackgroundColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#37bc9b"));
        private Color Green_PressColor = (Color)ColorConverter.ConvertFromString("#2b957a");
        private Color Green_MouseOverColor = (Color)ColorConverter.ConvertFromString("#2e9e83");

        private readonly Brush Purple_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#80877dc4"));
        private readonly Brush Purple_BackgroundColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#7266ba"));
        private readonly Color Purple_PressColor = (Color)ColorConverter.ConvertFromString("#564aa3");
        private readonly Color Purple_MouseOverColor = (Color)ColorConverter.ConvertFromString("#5b4eac");

        private readonly Brush Pink_BorderColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#80f751e9"));
        private readonly Brush Pink_BackgroundColor = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#f532e5"));
        private readonly Color Pink_PressColor = (Color)ColorConverter.ConvertFromString("#e90bd6");
        private readonly Color Pink_MouseOverColor = (Color)ColorConverter.ConvertFromString("#f30ee0");

        private Brush Secondary_FontColor = Brushes.Black;
        #endregion

        private Brush BorderColor
        {
            get { return (Brush)GetValue(BorderColorProperty); }
            set { SetValue(BorderColorProperty, value); }
        }

        public static DependencyProperty BorderColorProperty = DependencyProperty.Register(
          "BorderColor",
          typeof(Brush),
          typeof(BGYX_Button)
        );

        private Brush BackgroundColor
        {
            get { return (Brush)GetValue(BackgroundColorProperty); }
            set { SetValue(BackgroundColorProperty, value); }
        }

        public static DependencyProperty BackgroundColorProperty = DependencyProperty.Register(
          "BackgroundColor",
          typeof(Brush),
          typeof(BGYX_Button)
        );
        private Brush FontColor
        {
            get { return (Brush)GetValue(FontColorProperty); }
            set { SetValue(FontColorProperty, value); }
        }

        public static DependencyProperty FontColorProperty = DependencyProperty.Register(
          "FontColor",
          typeof(Brush),
          typeof(BGYX_Button)
        );

        public ColorStyleTypes ColorStyle
        {
            get { return (ColorStyleTypes)GetValue(ColorStyleProperty); }
            set { SetValue(ColorStyleProperty, value); }
        }

        public static readonly DependencyProperty ColorStyleProperty = DependencyProperty.Register(
          "ColorStyle",
          typeof(ColorStyleTypes),
          typeof(BGYX_Button),
          new FrameworkPropertyMetadata(ColorStyleTypes.Secondary, new PropertyChangedCallback(ReferenControlsCallback))
        );

        public ButtonIconPositions IconPosition
        {
            get { return (ButtonIconPositions)GetValue(IconPositionProperty); }
            set { SetValue(IconPositionProperty, value); }
        }

        public static readonly DependencyProperty IconPositionProperty = DependencyProperty.Register(
          "IconPosition",
          typeof(ButtonIconPositions),
          typeof(BGYX_Button),
          new FrameworkPropertyMetadata(ButtonIconPositions.Left, new PropertyChangedCallback(ReferenControlsCallback))
        );

        public Icons Icon
        {
            get { return (Icons)GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }

        public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
          "Icon",
          typeof(Icons),
          typeof(BGYX_Button),
          new FrameworkPropertyMetadata(Icons.None, new PropertyChangedCallback(ReferenControlsCallback))
        );

        public Brush IconColor
        {
            get { return (Brush)GetValue(IconColorProperty); }
            set { SetValue(IconColorProperty, value); }
        }

        public static readonly DependencyProperty IconColorProperty = DependencyProperty.Register(
          "IconColor",
          typeof(Brush),
          typeof(BGYX_Button),
          new FrameworkPropertyMetadata(Brushes.White)
        );

        private double ButtonRadius
        {
            get { return (double)GetValue(ButtonRadiusProperty); }
            set { SetValue(ButtonRadiusProperty, value); }
        }

        public static readonly DependencyProperty ButtonRadiusProperty = DependencyProperty.Register(
          "ButtonRadius",
          typeof(double),
          typeof(BGYX_Button),
          new FrameworkPropertyMetadata(3.0)
        );

        private Thickness IconMargin
        {
            get { return (Thickness)GetValue(IconMarginProperty); }
            set { SetValue(IconMarginProperty, value); }
        }

        public static readonly DependencyProperty IconMarginProperty = DependencyProperty.Register(
          "IconMargin",
          typeof(Thickness),
          typeof(BGYX_Button),
          new FrameworkPropertyMetadata(new Thickness(4))
        );

        public ButtonTypes ButtonType
        {
            get { return (ButtonTypes)GetValue(ButtonTypeProperty); }
            set { SetValue(ButtonTypeProperty, value); }
        }

        public static readonly DependencyProperty ButtonTypeProperty = DependencyProperty.Register(
          "ButtonType",
          typeof(ButtonTypes),
          typeof(BGYX_Button),
          new FrameworkPropertyMetadata(ButtonTypes.Normal, new PropertyChangedCallback(ReferenControlsCallback))
        );

        static BGYX_Button()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(BGYX_Button), new FrameworkPropertyMetadata(typeof(BGYX_Button)));
        }

        private static void ReferenControlsCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as BGYX_Button).ReferenControls();
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            ReferenControls();
        }

        public void ReferenControls()
        {
            var BGYX_Grid = this.Template?.FindName("BGYX_Grid", this) as Grid;
            if (BGYX_Grid != null)
            {
                switch (this.ColorStyle)
                {
                    case ColorStyleTypes.Secondary:
                        ReferenControlsByStyleType(BGYX_Grid, Secondary_BorderColor, Secondary_BackgroundColor, Secondary_MouseOverColor, Secondary_PressColor);
                        break;
                    case ColorStyleTypes.Primary:
                        ReferenControlsByStyleType(BGYX_Grid, Primary_BorderColor, Primary_BackgroundColor, Primary_MouseOverColor, Primary_PressColor);
                        break;
                    case ColorStyleTypes.Success:
                        ReferenControlsByStyleType(BGYX_Grid, Success_BorderColor, Success_BackgroundColor, Success_MouseOverColor, Success_PressColor);
                        break;
                    case ColorStyleTypes.Info:
                        ReferenControlsByStyleType(BGYX_Grid, Info_BorderColor, Info_BackgroundColor, Info_MouseOverColor, Info_PressColor);
                        break;
                    case ColorStyleTypes.Warning:
                        ReferenControlsByStyleType(BGYX_Grid, Warning_BorderColor, Warning_BackgroundColor, Warning_MouseOverColor, Warning_PressColor);
                        break;
                    case ColorStyleTypes.Danger:
                        ReferenControlsByStyleType(BGYX_Grid, Danger_BorderColor, Danger_BackgroundColor, Danger_MouseOverColor, Danger_PressColor);
                        break;
                    case ColorStyleTypes.Inverse:
                        ReferenControlsByStyleType(BGYX_Grid, Inverse_BorderColor, Inverse_BackgroundColor, Inverse_MouseOverColor, Inverse_PressColor);
                        break;
                    case ColorStyleTypes.Green:
                        ReferenControlsByStyleType(BGYX_Grid, Green_BorderColor, Green_BackgroundColor, Green_MouseOverColor, Green_PressColor);
                        break;
                    case ColorStyleTypes.Purple:
                        ReferenControlsByStyleType(BGYX_Grid, Purple_BorderColor, Purple_BackgroundColor, Purple_MouseOverColor, Purple_PressColor);
                        break;
                    case ColorStyleTypes.Pink:
                        ReferenControlsByStyleType(BGYX_Grid, Pink_BorderColor, Pink_BackgroundColor, Pink_MouseOverColor, Pink_PressColor);
                        break;
                }

                var IconGrid = this.Template?.FindName("IconGrid", this) as Grid;
                var ContentGrid = this.Template?.FindName("ContentGrid", this) as Grid;

                if (Icon == Icons.None)
                {
                    IconGrid.Visibility = Visibility.Collapsed;
                    Grid.SetColumn(IconGrid, 1);
                    Grid.SetColumn(ContentGrid, 0);
                    BGYX_Grid.ColumnDefinitions[0].Width = GridLengthUtil.DefaultStar;
                    BGYX_Grid.ColumnDefinitions[1].Width = GridLength.Auto;
                }
                else
                {
                    IconGrid.Visibility = Visibility.Visible;
                    if (IconPosition == ButtonIconPositions.Left)
                    {
                        Grid.SetColumn(IconGrid, 0);
                        Grid.SetColumn(ContentGrid, 1);

                        BGYX_Grid.ColumnDefinitions[0].Width = GridLength.Auto;
                        BGYX_Grid.ColumnDefinitions[1].Width = GridLengthUtil.DefaultStar;

                        IconMargin = new Thickness(4, 4, 0, 4);
                    }

                    if (IconPosition == ButtonIconPositions.Right)
                    {
                        Grid.SetColumn(IconGrid, 1);
                        Grid.SetColumn(ContentGrid, 0);

                        BGYX_Grid.ColumnDefinitions[0].Width = GridLengthUtil.DefaultStar;
                        BGYX_Grid.ColumnDefinitions[1].Width = GridLength.Auto;

                        IconMargin = new Thickness(0, 4, 4, 4);
                    }
                }

                if (ButtonType == ButtonTypes.Normal)
                {
                    ButtonRadius = 3;
                }

                if (ButtonType == ButtonTypes.Oval)
                {
                    ButtonRadius = 18;
                }

                if (ButtonType == ButtonTypes.Square)
                {
                    ButtonRadius = 0;
                }
            }
        }

        public void ReferenControlsByStyleType(FrameworkElement contentTemplate, Brush borderColor, Brush backgroundColor, Color mouseOverColor, Color pressColor)
        {
            if (this.ColorStyle == ColorStyleTypes.Secondary)
            {
                this.FontColor = Secondary_FontColor;
            }
            else
            {
                this.FontColor = Brushes.White;
            }

            var stateManager = VisualStateManager.GetVisualStateGroups(contentTemplate);
            foreach (VisualState state in (stateManager[0] as VisualStateGroup).States)
            {
                if (state.Storyboard?.Children.Count > 0)
                {
                    ColorAnimationUsingKeyFrames frame = state.Storyboard.Children[0] as ColorAnimationUsingKeyFrames;
                    if (state.Name == "MouseOver")
                    {
                        frame.KeyFrames[0].Value = mouseOverColor;
                    }
                    if (state.Name == "Pressed")
                    {
                        frame.KeyFrames[0].Value = pressColor;
                    }
                }
            }

            BorderColor = borderColor;
            BackgroundColor = backgroundColor;
        }

    }
}
